package com.cloud.sysmana.ser.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.cloud.sysmana.dto.FuncTree;
import com.cloud.sysmana.entity.SysFunc;
import com.cloud.sysmana.entity.SysRole;
import com.cloud.sysmana.entity.SysRoleFunc;
import com.cloud.sysmana.entity.dao.ISysFuncDao;
import com.cloud.sysmana.entity.dao.ISysRoleDao;
import com.cloud.sysmana.entity.dao.ISysRoleFuncDao;
import com.cloud.sysmana.ser.ISysFuncService;
import com.cloud.util.log.ALogFactory;
import com.cloud.util.other.StringUtil;

/**
 * 
 * 功能、岗位信息缓存
 * 
 * @version 1.0
 * @date 2016-04-18
 * @author gaof
 */
@Service
@Transactional
public class FuncRoleCacheService {

	/* 岗位分隔线 */
	public static final String roleSplit = ",";
	
	/* 功能列表 */
	private static ArrayList<SysFunc> FUNC_LIST;
	
	/* id_功能信息缓存 */
	private static HashMap<Integer, SysFunc> FUNC_ID_MAP;
	/* 功能标识_功能信息缓存 */
	private static HashMap<String, SysFunc> FUNC_URL_MAP;
	
	/* 岗位id_功能id信息缓存 */
	private static HashMap<Integer, ArrayList<Integer>> ROLE_FUNCID_ID_MAP;
	/* 岗位id_功能信息缓存 */
	private static HashMap<Integer, ArrayList<SysFunc>> ROLE_FUNC_ID_MAP;
	
	@Resource(name="sysFuncDao")
	private ISysFuncDao sysFuncDao;
	
	@Resource(name="sysRoleDao")
	private ISysRoleDao sysRoleDao;
	
	@Resource(name="sysRoleFuncDao")
	private ISysRoleFuncDao sysRoleFuncDao;
	
	/**
	 * 系统初始化时启动
	 */
	public void init() {
		
		reloadFunc();//缓存功能信息
		reloadRoleFunc();//缓存岗位权限信息
		
		ALogFactory.getLog().info("系统基础数据：功能、岗位数据加载成功");
	}
	
	/**
	 * 重新加载功能缓存
	 */
	public void reloadFunc(){
		
		if(FUNC_LIST == null){
			FUNC_LIST = new ArrayList<SysFunc>();
		}else{
			FUNC_LIST.clear();
		}
		
		if(FUNC_ID_MAP == null){
			FUNC_ID_MAP = new HashMap<Integer, SysFunc>();
		}else{
			FUNC_ID_MAP.clear();
		}
		
		if(FUNC_URL_MAP == null){
			FUNC_URL_MAP = new HashMap<String, SysFunc>();
		}else{
			FUNC_URL_MAP.clear();
		}
		
		/* 缓存功能 信息 */
		List<SysFunc> sysFuncList = sysFuncDao.loadAllFunc();
		for (SysFunc func : sysFuncList) {
			FUNC_ID_MAP.put(func.getFuncId(), func);
			if(!StringUtil.isEmpty(func.getFuncUrl()) && func.getFuncUrl().indexOf("?") > 0){
				FUNC_URL_MAP.put(func.getFuncUrl().substring(0, func.getFuncUrl().indexOf("?")), func);
			}else{
				FUNC_URL_MAP.put(func.getFuncUrl(), func);
			}
		}
		FUNC_LIST.addAll(sysFuncList);
	}
	
	/**
	 * 重新加载功能缓存
	 */
	public void reloadRoleFunc(){
		
		if(ROLE_FUNCID_ID_MAP == null){
			ROLE_FUNCID_ID_MAP = new HashMap<Integer, ArrayList<Integer>>();
		}else{
			ROLE_FUNCID_ID_MAP.clear();
		}
		
		if(ROLE_FUNC_ID_MAP == null){
			ROLE_FUNC_ID_MAP = new HashMap<Integer, ArrayList<SysFunc>>();
		}else{
			ROLE_FUNCID_ID_MAP.clear();
		}
		
		/* 缓存岗位职责信息 */
		List<SysRoleFunc> tempList = null;
		ArrayList<Integer> roleFuncIdList = null;
		ArrayList<SysFunc> roleFuncList = null;
		List<SysRole> sysRoleList = sysRoleDao.loadAll();//获取所有岗位
		for (SysRole role : sysRoleList) {
			roleFuncIdList = new ArrayList<Integer>();
			roleFuncList = new ArrayList<SysFunc>();
			tempList = sysRoleFuncDao.getRoleFuncByRoleId(role.getRoleId());// 根据岗位id获得岗位功能
			
			for (SysRoleFunc roleFunc : tempList) {
				SysFunc func = FUNC_ID_MAP.get(roleFunc.getId().getFuncId());
				if(func != null){
					roleFuncList.add(func);
					roleFuncIdList.add(roleFunc.getId().getFuncId());// 根据岗位功能连接记录的功能编号，获得功能id信息
				}
			}
			
			ROLE_FUNC_ID_MAP.put(role.getRoleId(), roleFuncList);
			ROLE_FUNCID_ID_MAP.put(role.getRoleId(), roleFuncIdList);
		}
	}
	
	/**
	 * 获取指定功能的功能树(本功能及其子功能）
	 * 
	 * @param func
	 * @return
	 */
	public FuncTree getFuncTree(FuncTree funcTree, List<SysFunc> roleFuncList) {

		List<SysFunc> funcList = getChildFunc(funcTree.getFunc().getFuncId(),
				roleFuncList);// 获取下级节点
		
		//没有下级节点
		if (null == funcList || 0 == funcList.size()) {
			funcTree.setChildFunc(new ArrayList<FuncTree>());
			funcTree.setFunc(funcTree.getFunc());
			return funcTree;
		}
		
		//有下级节点，清除功能列表中的下级节点，减少下次遍历次数
		roleFuncList.removeAll(funcList);
		
		/* 构建子节点 */
		ArrayList<FuncTree> funcTreeList = new ArrayList<FuncTree>();
		for (SysFunc func : funcList) {
			FuncTree funcTemp = new FuncTree();
			funcTemp.setFunc(func);
			funcTreeList.add(funcTemp);
		}
		funcTree.setChildFunc(funcTreeList);

		for (FuncTree funcTreeTemp : funcTreeList) {
			getFuncTree(funcTreeTemp, roleFuncList);
		}

		return funcTree;
	}
	
	/**
	 * 获取指定功能的下级功能
	 * 
	 * @param funcNo
	 *            ：功能编号
	 * @return
	 */
	public List<SysFunc> getChildFunc(int funcId, List<SysFunc> roleFuncList) {

		ArrayList<SysFunc> funcList = new ArrayList<SysFunc>();

		for (SysFunc func : roleFuncList) {
			if (funcId == func.getPid()) {
				funcList.add(func);
			}
		}

		return funcList;
	}
	
	/**
	 * 获取所有功能资源信息
	 * 
	 * @return
	 */
	public List<SysFunc> getFucList() {
		return FUNC_LIST;
	}
	
	/**
	 * 根据ID获取功能信息
	 * @param id
	 * @return
	 */
	public SysFunc getFuncById(int id) {
		return FUNC_ID_MAP.get(id);
	}
	
	/**
	 * 根据岗位id获得其所包含功能的id
	 * @param id
	 * @return
	 */
	public List<Integer> getRoleFuncIdByRoleId(Integer id) {
		return null == ROLE_FUNCID_ID_MAP.get(id) ? new ArrayList<Integer>()
				: ROLE_FUNCID_ID_MAP.get(id);
	}
	
	/**
	 * 获取所有公共访问资源
	 * 
	 * @return
	 */
	public List<SysFunc> getPubFucList() {
		ArrayList<SysFunc> sysFuncList = new ArrayList<SysFunc>();

		for (SysFunc func : FUNC_LIST) {
			if (ISysFuncService.FUNC_ACCE_TYPE_PUB.equals(func.getAcceType())) {
				sysFuncList.add(func);
			}
		}

		return sysFuncList;
	}
	
	/**
	 * 通过岗位id获取岗位信息
	 * @param roleId
	 * @return
	 */
	public List<SysFunc> getRoleFuncByRoleId(int roleId) {
		return null == ROLE_FUNC_ID_MAP.get(roleId) ? new ArrayList<SysFunc>()
				: ROLE_FUNC_ID_MAP.get(roleId);
	}
	
	/**
	 * 根据功能地址符获取功能信息
	 * 
	 * @param funcId
	 *            ：功能标识符
	 * @return
	 */
	public SysFunc getFuncByFuncUrl(String url) {
		return FUNC_URL_MAP.get(url);
	}
	
	/**
	 * 校验岗位是否有该权限
	 * @param funcId
	 * @param roleId
	 * @return
	 */
	public boolean checkVisoSec(int funcId, int roleId) {
		
		boolean vistorAble = false;
		List<SysFunc> roleFuncList = getRoleFuncByRoleId(roleId);// 根据岗位获取操作权限
		for (SysFunc sysFunc : roleFuncList) {
			if (sysFunc.getFuncId().equals(funcId)) {
				vistorAble = true;
				break;
			}
		}

		return vistorAble;
	}
	
	
	
	

	public ISysFuncDao getSysFuncDao() {
		return sysFuncDao;
	}

	public void setSysFuncDao(ISysFuncDao sysFuncDao) {
		this.sysFuncDao = sysFuncDao;
	}

	public ISysRoleFuncDao getSysRoleFuncDao() {
		return sysRoleFuncDao;
	}

	public void setSysRoleFuncDao(ISysRoleFuncDao sysRoleFuncDao) {
		this.sysRoleFuncDao = sysRoleFuncDao;
	}

	public ISysRoleDao getSysRoleDao() {
		return sysRoleDao;
	}

	public void setSysRoleDao(ISysRoleDao sysRoleDao) {
		this.sysRoleDao = sysRoleDao;
	}

}
